package com.kly.user.serviceImpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kly.service.MemberService;
import com.kly.user.chatterService.ChatterUserService;
import com.kly.user.constant.ConstantType;
import com.kly.user.constant.RedisKey;
import com.kly.user.db.dao.*;
import com.kly.user.db.entity.*;
import com.kly.user.dto.*;
import com.kly.user.dto.chatter.response.UserChatterModeDto;
import com.kly.user.enums.*;
import com.kly.user.mapper.UserMapper;
import com.kly.user.msgClient.MsgAPI;
import com.kly.user.service.DeviceService;
import com.kly.user.service.UserService;
import com.kly.user.utils.OtherSnowflake;
import com.kly.user.utils.ServiceUtils;
import com.kly.user.utils.UserSnowflake;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("deviceService")
public class DeviceServiceImpl implements DeviceService {

    private static Log logger = LogFactory.getLog(DeviceServiceImpl.class);

    @Resource
    UserMapper userMapper;
    @Resource
    UserDao userDao;
    @Resource
    UserAccountsDao userAccountsDao;
    @Resource
    UserAlbumsDao userAlbumsDao;
    @Resource
    UserAlbumsContentDao userAlbumsContentDao;
    @Resource
    private ChatterUserService chatterUserService;
    @Resource
    UserInterestsDao userInterestsDao;
    @Resource
    UserProfileDao userProfileDao;
    @Resource
    InterestDao interestDao;
    @Resource
    UserTurnOnsDao userTurnOnsDao;
    @Resource
    UserBehaviorGpsDao userBehaviorGpsDao;
    @Resource
    UserBehaviorWifiDao userBehaviorWifiDao;
    @Resource
    UserGreetingContentDao userGreetingContentDao;
    @Resource
    UserChatOnlineRecordDao chatOnlineRecordDao;
    @Resource
    UserBehaviorDeviceDao userBehaviorDeviceDao;
    @Resource
    private MemberService memberService;
    @Resource
    private UserConversationDao userConversationDao;
    @Resource
    private UserMsgUnreadNumDao userMsgUnreadNumDao;
    @Resource
    private UserWlmDao userWlmDao;
    @Resource
    private MsgAPI msgAPI;
    @Resource
    private UserConversationChatterDao userConversationChatterDao;
    /**
     * 用户GSP地理位置已授权
     */
    private static final Integer HAS_GRANT_PRIVILEGE = 1;
    /**
     * 取消授权
     */
    private static final Integer CANCEL_PRIVILEGE = 1;

    @NacosValue(value = "${chat.conversation.flag:1}", autoRefreshed = true)
    private Integer chatConversationFlag;



    /**
     * 添加设备信息
     *
     * @param deviceInfoDto 设备信息
     * @return
     */
    @Override
    public Response addDeviceInfo(DeviceInfoDto deviceInfoDto) {

        if (Objects.isNull(deviceInfoDto)) {
            return Response.error("The parameter deviceInfo should be empty!");
        }
        if (Objects.isNull(deviceInfoDto.getGps()) && CollectionUtils.isEmpty(deviceInfoDto.getWifilist())) {
            return Response.error("The gps and wifi validation failed, both gps and wifi are empty!");
        }

        if (Objects.nonNull(deviceInfoDto.getGps())) {
            final GpsDto gpsDto = deviceInfoDto.getGps();
            userBehaviorGpsDao.addGps(deviceInfoDto.getUserCode(), gpsDto.getState(), null, gpsDto.getCity(), gpsDto.getLng(), gpsDto.getLat());

            // 更新地理位置授权
            final UserEntity user = userDao.selectByUserCode(deviceInfoDto.getUserCode());
            user.setGpsPrivilege(HAS_GRANT_PRIVILEGE);
            userDao.updateByPrimaryKey(user);

        }
        if (CollectionUtils.isNotEmpty(deviceInfoDto.getWifilist())) {
            final List<WifiDto> wifiList = deviceInfoDto.getWifilist();
            final List<UserBehaviorWifiEntity> wifiEntities = wifiList.stream().map(o -> {
                UserBehaviorWifiEntity wifiEntity = new UserBehaviorWifiEntity();
                BeanUtils.copyProperties(o, wifiEntity);
                wifiEntity.setUserCode(deviceInfoDto.getUserCode());
                return wifiEntity;
            }).collect(Collectors.toList());
            userBehaviorWifiDao.batchInsertWifi(wifiEntities);
        }

        if (StringUtils.isNotEmpty(deviceInfoDto.getAppVersionName())) {
            UserBehaviorDeviceEntity deviceEntity = new UserBehaviorDeviceEntity();
            deviceEntity.setClientId(deviceEntity.getClientId());
            deviceEntity.setVersion(String.valueOf(deviceInfoDto.getAppVersion()));
            deviceEntity.setVersionCode(deviceInfoDto.getAppVersionName());
            userBehaviorDeviceDao.insert(deviceEntity);
        }

        if (chatConversationFlag != 1) {
            //清除过期聊天会话和聊天记录
            conversationRemove(deviceInfoDto.getUserCode());
        }

        return Response.ok();
    }

    @Override
    public Response grantPermissions(GrantPermissionsDto grantPermissionsDto) {
        final UserEntity user = userDao.selectByUserCode(grantPermissionsDto.getUserCode());
        if (Objects.isNull(user)) {
            return Response.error("User not exists in records");
        }
        if (PermissionTypeEnum.location.equals(grantPermissionsDto.getPermissionType())) {
            user.setGpsPrivilege(grantPermissionsDto.getGrantFlag());
            userDao.updateByPrimaryKey(user);
            return Response.ok();
        } else if (PermissionTypeEnum.notification.equals(grantPermissionsDto.getPermissionType())) {
            user.setNotificationPrivilege(grantPermissionsDto.getGrantFlag() == 1);
            userDao.updateByPrimaryKey(user);
            return Response.ok();
        }

        return Response.ok();
    }

    /**
     * 清除用户会话信息、聊天记录、wlm记录
     * @param userCode
     */
    private void conversationRemove(String userCode) {
        try {
            Response<Boolean> booleanResponse = memberService.ifMember(userCode);
            if (booleanResponse != null && booleanResponse.isSuccess()) {
                Calendar noMemberTime = Calendar.getInstance();//获取对日期操作的类对象
                if (booleanResponse.getData()) {
                    noMemberTime.add(Calendar.DATE, -7);
                } else {
                    noMemberTime.add(Calendar.DATE, -3);
                }
                List<UserConversationEntity> userConversationEntities = userConversationDao.getConversationByUserCode(userCode, noMemberTime.getTime());
                for (UserConversationEntity userConversationEntity : userConversationEntities) {
                    //清除用户会话信息、wlm记录
                    clearData(userConversationEntity);
                    //发送消息给前端 清除用户融云会话信息、聊天记录
                    msgAPI.conversationRemove(AppEnum.MEBOO, userCode, "conversationRemove ", userConversationEntity.getChatterUserCode());
                }
            }
        } catch (Exception e) {
            logger.error("conversationRemove error :{}", e.getMessage());
        }
    }

    /**
     * 清除用户会话信息、wlm记录
     *
     * @param conversation
     */
    private void clearData(UserConversationEntity conversation) {
        userConversationChatterDao.doDeleted(conversation.getUserCode(), conversation.getUserCodeFriend());
        userMsgUnreadNumDao.readMessage(conversation.getUserCode(), conversation.getUserCodeFriend());
        userWlmDao.removeOverEffectiveRecord(conversation.getUserCode(), conversation.getUserCodeFriend(), LikeEnum.LIKE_EACH_OTHER);
        userConversationChatterDao.doDeleted(conversation.getUserCodeFriend(), conversation.getUserCode());
        userMsgUnreadNumDao.readMessage(conversation.getUserCodeFriend(), conversation.getUserCode());
        userWlmDao.removeOverEffectiveRecord(conversation.getUserCodeFriend(), conversation.getUserCode(), LikeEnum.LIKE_EACH_OTHER);
    }
}
